package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strings"
	"time"
)

const (
	versionUrl = "http://hs.blizzard.cn/gameguide/#version"     //展示版本信息的页面
	cardsUrl   = "http://hs.blizzard.cn/action/gameguide/cards" //可以post 版本名称，获得所有卡牌图片链接地址
	cardSet    = "cardSet"
	pictureDir = "../download/"
)

func main() {
	begin := time.Now()
	versions, err := getVersionsInfo()
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", versions)

	for _, v := range versions {
		time.Sleep(5 * time.Second)
		data, err := getCardsByName(v)
		if err != nil {
			panic(err)
		}
		fmt.Println(v, ":", len(data.Data))
		//downloadCards(v, data)

		fmt.Println("download ", v, " finish ...")
	}
	fmt.Printf("use %.02f to download all cards\n", time.Since(begin))
}

//根据url 得到的内容，使用正则表达式，将版本的名称读取出来
func getVersionsInfo() (versions []string, err error) {
	resp, err := http.Get(versionUrl)
	if err != nil {
		return versions, err
	}
	defer resp.Body.Close()

	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return versions, err
	}
	//fmt.Println(string(bytes))
	//通过正则得到每个版本的
	//<a class="expansion-link expansion-link--msog" href="/gameguide/msog/">

	re := regexp.MustCompile(`<a class="expansion-link .+" href="/gameguide/(.+)/"`)
	match := re.FindAllStringSubmatch(string(bytes), -1)
	//fmt.Println(len(match))
	for _, v := range match {
		//fmt.Printf("k:%d v:%s len:%d %s\n", k, v, len(v), v[1])
		if len(v) > 1 {
			versions = append(versions, v[1])
		}
	}
	return versions, err
}

//根据版本名称获取所有卡牌，用到post请求
func getCardsByName(version string) (data responseData, err error) {
	//注意参数是否正确
	request, err := http.NewRequest(http.MethodPost, cardsUrl, strings.NewReader(cardSet+"="+version))
	if err != nil {
		return data, err
	}
	//fmt.Println(request)
	client := http.Client{}
	//注意这里content-type是需要设置的
	request.Header.Set("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
	resp, err := client.Do(request)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return data, err
	}

	err = json.Unmarshal(bytes, &data)
	if err != nil {
		return data, err
	}

	return data, err
}

//根据json数据下载文件
//创建version对应的目录，同时根据url的前缀，同时创建各个职业的文件夹
func downloadCards(version string, data responseData) {
	version = pictureDir + version
	checkDirAndCreate(version)
	for _, v := range data.Data {
		race, pictureName, err := getRaceAndNameByUrl(v.Address)
		if err != nil {
			continue
		}
		dstPath := version + "/" + race
		checkDirAndCreate(dstPath)
		result, err := getPictureByUrl(v.Address)
		if err != nil {
			fmt.Println(err)
			continue
		}
		//fmt.Println(dstPath)
		ioutil.WriteFile(dstPath+"/"+pictureName, result, 0644)
	}
}

//判断一个文件夹是否存在，如果不存在，则创建
func checkDirAndCreate(dir string) (err error) {
	_, err = os.Stat(dir)
	if err != nil {
		if !os.IsExist(err) {
			os.Mkdir(dir, os.ModePerm)
		} else {
			return err
		}
	}
	return err
}

func getRaceAndNameByUrl(url string) (race, name string, err error) {
	png := strings.Split(url, "/")
	pngName := png[len(png)-1]
	raceInfo := strings.Split(pngName, "_")
	race = raceInfo[0]
	return race, pngName, nil
}

//根据图片地址获得图片
func getPictureByUrl(url string) (data []byte, err error) {
	//fmt.Println(url)
	resp, err := http.Get(url)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()

	data, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return data, err
	}

	return data, err
}
